#include "PlayersStatsShowMenu.h"
#include "StringUtilities.h"
#include "Utilities.h"
#include "PrintUtilities.h"
#include "MenuManager.h"
#include "ServiceProvider.h"
#include "PeopleManager.h"
#include "TeamManager.h"
#include "GamePrintUtils.h"
#include "People.h"
#include "PeopleFunctors.h"
#include "PlayerMenu.h"
#include "Global.h"

#include "StlStringAndStreams.h"

PlayersStatsShowMenu::PlayersStatsShowMenu(MenuManager* const i_menuManager)
	:Menu(i_menuManager)
	,m_lastOption(NUM_FIXED_OPTIONS-1)
{
}

void PlayersStatsShowMenu::OnEnter()
{
	Input(Utilities::IntToStlString(m_lastOption));
}

void PlayersStatsShowMenu::Draw() const
{
	using namespace STD;
	using namespace Utilities;
	const int tab = Consts::SCREEN_WIDTH/2;

	cout << Print::Title("PLAYERS STATISTICS:");
	cout << TabUpTo(" 1) Sort by Player Age Up", tab) << " 2) Sort by Player Age Down" << endl;
	cout << TabUpTo(" 3) Sort by Age Up", tab) << " 4) Sort by Age Down" << endl;
	cout << TabUpTo(" 5) Sort by Num Player Seasons", tab) << " 6) Sort by Num Total Seasons" << endl;
	cout << TabUpTo(" 7) Sort by Total Num Injuries", tab) << " 8) Sort by Total Days of Injuries" << endl;
	cout << TabUpTo(" 9) Sort by Goalkeaping", tab) << "10) Sort by Max Goalkeeping" << endl;
	cout << TabUpTo("11) Sort by Defense", tab) << "12) Sort by Max Defense" << endl;
	cout << TabUpTo("13) Sort by Attacking", tab) << "14) Sort by Max Attacking" << endl;
	cout << TabUpTo("15) Sort by Resistence", tab) << "16) Sort by Salary" << endl;
	cout << TabUpTo("17) Sort by Fatigue", tab) << "18) Sort by Stamina" << endl;
	cout << TabUpTo("19) Sort by Intelligence", tab) << "20) Sort by Charisma" << endl;
	cout << TabUpTo("21) Sort by Aggressivity", tab) << "22) Sort By Bad Discipline" << endl;
	cout << TabUpTo("23) Sort by Season Played Matches", tab) << "24) Sort by Season Goals" << endl;
	cout << TabUpTo("25) Sort by Total Played Matches", tab) << "26) Sort by Total Matches" << endl;
	cout << TabUpTo("27) Sort by Season Evaluation", tab) << "28) Sort by Total Evaluation" << endl;
	cout << TabUpTo("29) Sort by Season Man Of The Match", tab) << "30) Sort by Total Man Of The Match" << endl;
	cout << TabUpTo("31) Sort by Total Goals", tab) << "32) Sort by Total Goals Ratio" << endl;

	cout << endl << endl;

	ShowPlayers();
}

void PlayersStatsShowMenu::ShowPlayers() const
{
	using STD::cout;
	using STD::endl;
	using namespace Utilities;
	
	const int maxPlayerNameSize = STL::min(People::GetParams().MAX_CHAR_NAME, 14u);
	const int maxTeamNameSize = STL::min(Team::GetParams().MAX_CHAR_TEAM_NAME, 8u);

	cout << TabUpTo("N", 4);
	cout << TabUpTo("NAME", maxPlayerNameSize);
	cout << TabUpTo("TEAM", maxTeamNameSize);
	cout << TabUpTo("YS", 3);
	cout << TabUpTo("NS", 3);
	cout << TabUpTo("ATK", 4);
	cout << TabUpTo("DEF", 4);
	cout << TabUpTo("GLK", 4);
	cout << TabUpTo("MXA", 4);
	cout << TabUpTo("MXD", 4);
	cout << TabUpTo("MXG", 4);
	cout << TabUpTo("RES", 4);
	cout << TabUpTo("AGG", 4);
	cout << TabUpTo("SAL", 5);
	cout << TabUpTo("NM", 3);
	cout << TabUpTo("EVAL", 5);
	cout << TabUpTo("MM", 3);
	cout << TabUpTo("GL", 4);
	cout << TabUpTo("RAT", 5);
	cout << TabUpTo("NMT", 4);
	cout << TabUpTo("EVAL", 5);
	cout << TabUpTo("MMT", 4);
	cout << TabUpTo("GLT", 5);
	cout << TabUpTo("RAT", 5);
	cout << TabUpTo("INJ", 4);
	cout << TabUpTo("DIS", 3);
	cout << endl;

	size_t counter = NUM_FIXED_OPTIONS;

	size_t maxSize = STL::min<size_t>(People::NUM_HOF_PEOPLE, m_players.size());
	for(size_t i=0; i<maxSize; ++i)
	{
		const People& thePlayer = *m_players.at(i);
		cout << TabUpTo(++counter, 4);
		cout << TabUpTo(thePlayer.GetName().substr(0, maxPlayerNameSize-1), maxPlayerNameSize);
		cout << TabUpTo(GetTeamName(thePlayer, GetSP()->GetTeamMgr().GetTeamName(thePlayer.GetTeamID())).substr(0,maxTeamNameSize-1), maxTeamNameSize);
		cout << TabUpTo(thePlayer.GetHistory().GetPlayerAge(), 3);
		cout << TabUpTo(thePlayer.GetHistory().GetNumSeason(StatusPlayer), 3);
		cout << TabUpTo(thePlayer.GetSkills().m_playerSkills[Attacker], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_playerSkills[Defender], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_playerSkills[Goalkeeper], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_maxPlayerSkills[Attacker], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_maxPlayerSkills[Defender], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_maxPlayerSkills[Goalkeeper], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_physicsSkills[Resistance], 4);
		cout << TabUpTo(thePlayer.GetSkills().m_mentalSkills[Aggressivity], 4);
		cout << TabUpTo(thePlayer.GetSalary(), 5);
		cout << TabUpTo(thePlayer.GetHistory().GetMatch(), 3);
		cout << TabUpTo(thePlayer.GetHistory().GetEvalStr(), 5);
		cout << TabUpTo(thePlayer.GetHistory().GetMoM(), 3);
		cout << TabUpTo(thePlayer.GetHistory().GetScoredGoal(), 4);
		cout << TabUpTo(Utilities::RatioToString(thePlayer.GetHistory().GetScoredGoalRatio()), 5);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalMatch(StatusPlayer), 4);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalEvalStr(), 5);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalMoM(), 4);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalScoredGoal(), 5);
		cout << TabUpTo(Utilities::RatioToString(thePlayer.GetHistory().GetTotalScoredGoalRatio()), 5);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalNumOfInjuryDays(), 4);
		cout << TabUpTo(thePlayer.GetHistory().GetTotalDisciplinePoints(), 3);
		cout << endl;
	}

	STL::string options;

	if(counter > NUM_FIXED_OPTIONS)
	{
		cout << endl;
		options =	"1-" + 
					Utilities::IntToStlString(NUM_FIXED_OPTIONS) +
					") Select Sorting Criterion.\n" +
					Utilities::IntToStlString(NUM_FIXED_OPTIONS+1) +
					"-" +
					Utilities::IntToStlString(counter) + 
					") Select People\n\n0) Return to previous menu'.";
	}
	else
	{
		cout << endl;
		cout << Utilities::TabUpTo("No Players Entry", 20);
		cout << endl;
		cout << endl;
		options =	"1-" +
					Utilities::IntToStlString(NUM_FIXED_OPTIONS) +
					") Select Sorting Criterion.\n\n0) Return to previous menu'.";
	}

	cout << Print::Options(options) << "Selection: ";
}

bool PlayersStatsShowMenu::Input(const STL::string& i_input)
{
	bool goodInput = true;
	const size_t res = Utilities::StringToInt(i_input);
	if(res > NUM_FIXED_OPTIONS && res <= NUM_FIXED_OPTIONS + STD::min<size_t>(People::NUM_HOF_PEOPLE, m_players.size()))
	{
		PlayerMenu* nextMenu = static_cast<PlayerMenu*>(GetMM()->GetPlayerMenu());
		const unsigned int temp = res-NUM_FIXED_OPTIONS-1;
		nextMenu->SetPlayer(m_players[temp]);
		GetMM()->PushMenu(nextMenu);
		return true;
	}

	int oldOpt = m_lastOption;
	m_lastOption = res;

	switch(res)
	{
	case 0:
		GetMM()->SetMenu(GetMM()->GetPlayersStatsMenu());
		m_lastOption = oldOpt;
		break;
	case 1:
		Utilities::Sort(m_players, PeopleComparisonPlayerAgeUp);
		break;
	case 2:
		Utilities::Sort(m_players, PeopleComparisonPlayerAgeDown);
		break;
	case 3:
		Utilities::Sort(m_players, PeopleComparisonAgeUp);
		break;
	case 4:
		Utilities::Sort(m_players, PeopleComparisonAgeDown);
		break;
	case 5:
		Utilities::Sort(m_players, PeopleComparisonNumSeason(StatusPlayer));
		break;
	case 6:
		Utilities::Sort(m_players, PeopleComparisonNumSeason(StatusPlayerOrTrainer));
		break;
	case 7:
		Utilities::Sort(m_players, PeopleComparisonTotalNumInjury);
		break;
	case 8:
		Utilities::Sort(m_players, PeopleComparisonTotalDayInjury);
		break;
	case 9:
		Utilities::Sort(m_players, PeopleComparisonSkill(Goalkeeper));
		break;
	case 10:
		Utilities::Sort(m_players, PeopleComparisonMaxSkill(Goalkeeper));
		break;
	case 11:
		Utilities::Sort(m_players, PeopleComparisonSkill(Defender));
		break;
	case 12:
		Utilities::Sort(m_players, PeopleComparisonMaxSkill(Defender));
		break;
	case 13:
		Utilities::Sort(m_players, PeopleComparisonSkill(Attacker));
		break;
	case 14:
		Utilities::Sort(m_players, PeopleComparisonMaxSkill(Attacker));
		break;
	case 15:
		Utilities::Sort(m_players, PeopleComparisonResistance);
		break;
	case 16:
		Utilities::Sort(m_players, PeopleComparisonSalary);
		break;
	case 17:
		Utilities::Sort(m_players, PeopleComparisonFatigue);
		break;
	case 18:
		Utilities::Sort(m_players, PeopleComparisonStamina);
		break;
	case 19:
		Utilities::Sort(m_players, PeopleComparisonIntelligence);
		break;
	case 20:
		Utilities::Sort(m_players, PeopleComparisonCharisma);
		break;
	case 21:
		Utilities::Sort(m_players, PeopleComparisonAgressivity);
		break;
	case 22:
		Utilities::Sort(m_players, PeopleComparisonTotalDisciplinePoints);
		break;
	case 23:
		Utilities::Sort(m_players, PeopleComparisonMatch);
		break;
	case 24:
		Utilities::Sort(m_players, PeopleComparisonGoal);
		break;
	case 25:
		Utilities::Sort(m_players, PeopleComparisonTotalMatch(StatusPlayer));
		break;
	case 26:
		Utilities::Sort(m_players, PeopleComparisonTotalMatch(StatusPlayerOrTrainer));
		break;
	case 27:
		Utilities::Sort(m_players, PeopleComparisonEvaluation);
		break;
	case 28:
		Utilities::Sort(m_players, PeopleComparisonTotalEvaluation);
		break;
	case 29:
		Utilities::Sort(m_players, PeopleComparisonMoM);
		break;
	case 30:
		Utilities::Sort(m_players, PeopleComparisonTotalMoM);
		break;
	case 31:
		Utilities::Sort(m_players, PeopleComparisonTotalGoal);
		break;
	case 32:
		Utilities::Sort(m_players, PeopleComparisonTotalGoalRatio);
		break;
	default:
		goodInput = false;
		m_lastOption = oldOpt;
		break;
	};

	return goodInput;
}
